package com.itjcloud.iot.gateway.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.DefaultDataBufferFactory;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.util.Assert;
import reactor.core.publisher.Mono;

import java.nio.charset.StandardCharsets;
import java.util.Optional;


@Data
@AllArgsConstructor
public class IotSignatureBO {


    /**
     * 时间错
     */
    private String timestamp;


    /**
     * 随机字符
     */
    private String nonce;


    /**
     * 物联网设备id
     */
    private String deviceId;


    /**
     * get参数
     */
    private String query;

    /**
     * 签名
     */
    private String signature;

    //没有签名, 直接不校验. 如果有签名但是其他的没有抛出参数异常
    public static Mono<IotSignatureBO> init(ServerHttpRequest serverHttpRequest) {
        String signature = getHeader(serverHttpRequest, SignatureEnum.SIGNATURE);
        if (signature == null) {
            return Mono.empty();
        }

        String timestamp = getHeader(serverHttpRequest, SignatureEnum.TIMESTAMP);
        Assert.notNull(timestamp, "参数timestamp不能为空");


        String nonce = getHeader(serverHttpRequest, SignatureEnum.NONCE);
        Assert.notNull(nonce, "参数nonce不能为空");
        String deviceId = getHeader(serverHttpRequest, SignatureEnum.DEVICE_ID);
        Assert.notNull(deviceId, "参数deviceId不能为空");
        String query = Optional.ofNullable(serverHttpRequest.getURI().getQuery()).orElse("");
        return Mono.just(new IotSignatureBO(timestamp, nonce, deviceId, query, signature));
    }

    private static String getHeader(ServerHttpRequest request, SignatureEnum headerEnum) {
        return request.getHeaders().getFirst(headerEnum.getHeaderName());
    }

    public Mono<DataBuffer> createDataBuffer() {
        return Mono.defer(() -> {
            String body = this.timestamp + this.nonce + this.deviceId + this.query;
            DataBufferFactory dataBufferFactory = DefaultDataBufferFactory.sharedInstance;
            DataBuffer dataBuffer = dataBufferFactory.wrap(body.getBytes(StandardCharsets.UTF_8));
            return Mono.just(dataBuffer);
        });
    }

}
